//check whether use external fmt library
#if 0
#ifdef SPDLOG_FMT_EXTERNAL
#include <fmt/format.h>
#endif
#endif
#include <spdlog/sinks/basic_file_sink.h>
#include <spdlog/sinks/stdout_color_sinks.h>
#include <spdlog/spdlog.h>

#include <memory>

// logger
class Logger
{
public:
    static void init()
    {
        // create console and file logger
        auto console_sink = std::make_shared<spdlog::sinks::stdout_color_sink_st>();
        // use relative path and ensure file is accessible
        std::shared_ptr<spdlog::sinks::basic_file_sink_mt> file_sink;
        try
        {
            file_sink = std::make_shared<spdlog::sinks::basic_file_sink_mt>("./cuda_test.log", true);
        }
        catch (const std::exception& e)
        {
            // if file creation fails, use console output only
            spdlog::warn("Failed to create file sink: {}", e.what());
            auto logger = std::make_shared<spdlog::logger>("cuda_test", spdlog::sinks_init_list{console_sink});
            logger->set_level(spdlog::level::debug);
            spdlog::set_default_logger(logger);
            return;
        }

        // set log level
        console_sink->set_level(spdlog::level::info);
        file_sink->set_level(spdlog::level::debug);

        // create multi-sink logger
        auto logger = std::make_shared<spdlog::logger>("cuda_test", spdlog::sinks_init_list{console_sink, file_sink});
        logger->set_level(spdlog::level::debug);

        // set as default logger
        spdlog::set_default_logger(logger);
    }

    static std::shared_ptr<spdlog::logger> getLogger() { return spdlog::get("cuda_test"); }
};

// log macros
#define MYINFO(...) spdlog::info(__VA_ARGS__)
#define MYDEBUG(...) spdlog::debug(__VA_ARGS__)
#define MYWARN(...) spdlog::warn(__VA_ARGS__)
#define MYERROR(...) spdlog::error(__VA_ARGS__)